from pywebio import start_server, config
from pywebio.output import *
from pywebio.input import *
from pywebio.session import set_env
import requests
import json
from datetime import datetime

# 配置后端API地址（请根据实际后端部署地址修改）
API_BASE = "http://localhost:8000/api"


@config(title="银行业务系统", description="账户管理与交易平台")
def main():
    """主页面逻辑：显示功能菜单并处理用户选择"""
    set_env(auto_scroll_bottom=True, title="银行业务系统")

    while True:
        clear()  # 清空当前页面内容
        put_header("银行业务系统")  # 页面标题
        put_div(style="text-align:center; margin:20px 0;")

        # 功能菜单
        choice = radio(
            "请选择操作",
            options=[
                "1. 账户注册", "2. 账户查询", "3. 存款",
                "4. 取款", "5. 转账", "6. 交易记录", "0. 退出"
            ],
            type="horizontal",  # 水平排列选项
            value="1"  # 默认选中第一个选项
        )

        # 根据选择执行对应功能
        if choice == "0":
            put_success("感谢使用，再见！")
            break

        elif choice == "1":
            register_account()
        elif choice == "2":
            query_account()
        elif choice == "3":
            deposit_money()
        elif choice == "4":
            withdraw_money()
        elif choice == "5":
            transfer_money()
        elif choice == "6":
            query_transactions()

        # 显示"继续操作"按钮
        put_buttons(["继续操作"], onclick=[lambda _: None])
        put_br()


def register_account():
    """账户注册功能页面"""
    put_markdown("## 🔑 账户注册")
    put_text("请填写以下信息创建新账户")
    put_br()

    # 注册表单
    form_data = input_group(
        "账户信息",
        [
            input(
                "账户ID",
                name="account_id",
                placeholder="请输入6-20位字母或数字",
                required=True,
                type=TEXT,
                validate=lambda x: "账户ID长度需在6-20位之间" if len(x) < 6 or len(x) > 20 else None
            ),
            input(
                "姓名",
                name="owner_name",
                placeholder="请输入真实姓名",
                required=True,
                type=TEXT,
                validate=lambda x: "姓名不能为空" if not x.strip() else None
            ),
            input(
                "密码",
                name="password",
                placeholder="请输入6-16位密码",
                required=True,
                type=PASSWORD,
                validate=lambda x: "密码长度需在6-16位之间" if len(x) < 6 or len(x) > 16 else None
            ),
            input(
                "确认密码",
                name="confirm_password",
                placeholder="请再次输入密码",
                required=True,
                type=PASSWORD,
                validate=lambda x, data: "两次密码不一致" if x != data['password'] else None
            )
        ],
        validate=lambda data: "账户ID已存在" if check_account_exists(data["account_id"]) else None
    )

    try:
        # 发送注册请求到后端API
        response = requests.post(
            f"{API_BASE}/account/create",
            json={
                "account_id": form_data["account_id"],
                "owner_name": form_data["owner_name"],
                "password": form_data["password"]
            }
        )
        result = response.json()

        if result["success"]:
            put_success("账户创建成功！")
            put_table([
                ["账户ID", form_data["account_id"]],
                ["姓名", form_data["owner_name"]],
                ["创建时间", datetime.now().strftime("%Y-%m-%d %H:%M:%S")]
            ], header=["信息项", "值"])
        else:
            put_error(f"注册失败：{result.get('detail', '未知错误')}")

    except requests.exceptions.ConnectionError:
        put_error("无法连接到后端服务，请检查API地址是否正确")
    except Exception as e:
        put_error(f"注册过程中发生错误：{str(e)}")


def query_account():
    """账户查询功能页面"""
    put_markdown("## 🔍 账户查询")
    put_text("请输入账户ID查询账户信息")
    put_br()

    # 账户查询表单
    account_id = input(
        "账户ID",
        placeholder="请输入要查询的账户ID",
        required=True,
        type=TEXT
    )

    try:
        # 发送查询请求到后端API
        response = requests.get(f"{API_BASE}/account/{account_id}")
        result = response.json()

        if result["success"]:
            data = result["data"]
            put_success("账户信息查询成功！")
            put_table([
                ["账户ID", data["account_id"]],
                ["姓名", data["owner_name"]],
                ["账户类型", "储蓄账户" if data["account_type"] == "savings" else "支票账户"],
                ["当前余额", f"¥{data['balance']:.2f}"],
                ["创建时间", data["create_time"]]
            ], header=["信息项", "值"])
        else:
            put_error(f"查询失败：{result.get('detail', '未知错误')}")

    except requests.exceptions.ConnectionError:
        put_error("无法连接到后端服务，请检查API地址是否正确")
    except Exception as e:
        put_error(f"查询过程中发生错误：{str(e)}")


def deposit_money():
    """存款功能页面"""
    put_markdown("## 💳 存款")
    put_text("请输入账户ID和存款金额")
    put_br()

    # 存款表单
    form_data = input_group(
        "存款信息",
        [
            input(
                "账户ID",
                name="account_id",
                placeholder="请输入存款账户ID",
                required=True,
                type=TEXT
            ),
            float_input(
                "存款金额",
                name="amount",
                placeholder="请输入存款金额（需大于0）",
                required=True,
                min_value=0.01,
                step=0.01,
                validate=lambda x: "金额必须大于0" if x <= 0 else None
            )
        ]
    )

    try:
        # 发送存款请求到后端API
        response = requests.post(
            f"{API_BASE}/account/deposit",
            json={
                "account_id": form_data["account_id"],
                "amount": form_data["amount"]
            }
        )
        result = response.json()

        if result["success"]:
            put_success(f"存款成功！金额：¥{form_data['amount']:.2f}")
            put_text(f"当前余额：¥{result['data']['balance']:.2f}")
        else:
            put_error(f"存款失败：{result.get('detail', '未知错误')}")

    except requests.exceptions.ConnectionError:
        put_error("无法连接到后端服务，请检查API地址是否正确")
    except Exception as e:
        put_error(f"存款过程中发生错误：{str(e)}")


def withdraw_money():
    """取款功能页面"""
    put_markdown("## 💸 取款")
    put_text("请输入账户ID、取款金额和密码")
    put_br()

    # 取款表单
    form_data = input_group(
        "取款信息",
        [
            input(
                "账户ID",
                name="account_id",
                placeholder="请输入取款账户ID",
                required=True,
                type=TEXT
            ),
            float_input(
                "取款金额",
                name="amount",
                placeholder="请输入取款金额（需大于0）",
                required=True,
                min_value=0.01,
                step=0.01,
                validate=lambda x: "金额必须大于0" if x <= 0 else None
            ),
            input(
                "账户密码",
                name="password",
                placeholder="请输入账户密码",
                required=True,
                type=PASSWORD
            )
        ]
    )

    try:
        # 发送取款请求到后端API
        response = requests.post(
            f"{API_BASE}/account/withdraw",
            json=form_data
        )
        result = response.json()

        if result["success"]:
            put_success(f"取款成功！金额：¥{form_data['amount']:.2f}")
            put_text(f"当前余额：¥{result['data']['balance']:.2f}")
        else:
            put_error(f"取款失败：{result.get('detail', '未知错误')}")

    except requests.exceptions.ConnectionError:
        put_error("无法连接到后端服务，请检查API地址是否正确")
    except Exception as e:
        put_error(f"取款过程中发生错误：{str(e)}")


def transfer_money():
    """转账功能页面"""
    put_markdown("## 🔄 转账")
    put_text("请输入转出账户、转入账户和转账金额")
    put_br()

    # 转账表单
    form_data = input_group(
        "转账信息",
        [
            input(
                "转出账户ID",
                name="from_account_id",
                placeholder="请输入转出账户ID",
                required=True,
                type=TEXT
            ),
            input(
                "转入账户ID",
                name="to_account_id",
                placeholder="请输入转入账户ID",
                required=True,
                type=TEXT,
                validate=lambda x, data: "不能向自己转账" if x == data['from_account_id'] else None
            ),
            float_input(
                "转账金额",
                name="amount",
                placeholder="请输入转账金额（需大于0）",
                required=True,
                min_value=0.01,
                step=0.01,
                validate=lambda x: "金额必须大于0" if x <= 0 else None
            ),
            input(
                "转出账户密码",
                name="password",
                placeholder="请输入转出账户密码",
                required=True,
                type=PASSWORD
            )
        ],
        validate=lambda data: "转入账户不存在" if not check_account_exists(data["to_account_id"]) else None
    )

    try:
        # 发送转账请求到后端API
        response = requests.post(
            f"{API_BASE}/transaction/transfer",
            json=form_data
        )
        result = response.json()

        if result["success"]:
            put_success(f"转账成功！金额：¥{form_data['amount']:.2f}")
            put_text(f"从 {form_data['from_account_id']} 转入 {form_data['to_account_id']}")
        else:
            put_error(f"转账失败：{result.get('detail', '未知错误')}")

    except requests.exceptions.ConnectionError:
        put_error("无法连接到后端服务，请检查API地址是否正确")
    except Exception as e:
        put_error(f"转账过程中发生错误：{str(e)}")


def query_transactions():
    """交易记录查询功能页面"""
    put_markdown("## 📊 交易记录")
    put_text("请输入账户ID查询交易历史")
    put_br()

    # 交易记录查询表单
    account_id = input(
        "账户ID",
        placeholder="请输入要查询的账户ID",
        required=True,
        type=TEXT
    )

    try:
        # 发送查询请求到后端API
        response = requests.get(f"{API_BASE}/transaction/history/{account_id}")
        result = response.json()

        if result["success"]:
            transactions = result["data"]
            if not transactions:
                put_info("该账户暂无交易记录")
            else:
                put_success(f"查询到 {len(transactions)} 条交易记录")
                # 渲染交易记录表格
                table_data = [
                    ["交易ID", "交易类型", "金额", "时间", "状态"]
                ]
                for tx in transactions:
                    tx_type = "转出" if tx["from_account_id"] == account_id else "转入"
                    table_data.append([
                        tx["transaction_id"][:8] + "..." + tx["transaction_id"][-4:],
                        tx_type,
                        f"¥{abs(tx['amount']):.2f}",
                        tx["transaction_time"],
                        "✅ 成功" if tx["status"] == "成功" else "❌ 失败"
                    ])
                put_table(table_data)
        else:
            put_error(f"查询失败：{result.get('detail', '未知错误')}")

    except requests.exceptions.ConnectionError:
        put_error("无法连接到后端服务，请检查API地址是否正确")
    except Exception as e:
        put_error(f"查询过程中发生错误：{str(e)}")


def check_account_exists(account_id: str) -> bool:
    """检查账户是否存在（前端辅助验证）"""
    try:
        response = requests.get(f"{API_BASE}/account/{account_id}")
        result = response.json()
        return result["success"]
    except:
        return False


if __name__ == "__main__":
    # 启动前端服务（默认端口8080，可通过port参数修改）
    start_server(main, port=8080, debug=True)